package com.wust.modules.online.config.util;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;

import com.wust.modules.online.config.service.DbTableHandle;
import com.wust.modules.online.config.service.impl.OracleDbTableHandle;
import lombok.extern.slf4j.Slf4j;
import com.wust.common.util.SpringContextUtils;
import com.wust.common.util.oConvertUtils;
import com.wust.modules.online.config.exception.DBException;
import com.wust.modules.online.config.service.impl.MySqlDbTableHandle;
import com.wust.modules.online.config.service.impl.POSTGRESQLDbTableHandle;
import com.wust.modules.online.config.service.impl.SqlServerDbTableHandle;

/**
 * @author waheng
 */
@Slf4j
public class TableUtil {
    public static String a = "";


    public static DbTableHandle getTableHandle() throws SQLException, DBException {
        Object object = null;
        String databaseType = getDatabaseType();
        byte bt = -1;
        switch(databaseType.hashCode()) {
            case -1955532418:
                if ("ORACLE".equals(databaseType)) {
                    bt = 1;
                }
                break;
            case -1620389036:
                if ("POSTGRESQL".equals(databaseType)) {
                    bt = 3;
                }
                break;
            case 73844866:
                if ("MYSQL".equals(databaseType)) {
                    bt = 0;
                }
                break;
            case 912124529:
                if ("SQLSERVER".equals(databaseType)) {
                    bt = 2;
                }
            default:
        }

        switch(bt) {
            case 0:
                object = new MySqlDbTableHandle();
                break;
            case 1:
                object = new OracleDbTableHandle();
                break;
            case 2:
                object = new SqlServerDbTableHandle();
                break;
            case 3:
                object = new POSTGRESQLDbTableHandle();
            default:
        }

        return (DbTableHandle) object;
    }

    public static Connection getConnection() throws SQLException {
        DataSource dataSource = (DataSource) SpringContextUtils.getApplicationContext().getBean(DataSource.class);
        return dataSource.getConnection();
    }

    public static String getDatabaseType() throws SQLException, DBException {
        if (oConvertUtils.isNotEmpty(a)) {
            return a;
        } else {
            DataSource dataSource = (DataSource)SpringContextUtils.getApplicationContext().getBean(DataSource.class);
            return getConnectionType(dataSource);
        }
    }


    public static String getConnectionType(DataSource dataSource) throws SQLException, DBException {
        if ("".equals(a)) {
            Connection connection = dataSource.getConnection();

            try {
                DatabaseMetaData databaseMetaData = connection.getMetaData();
                String lowerCase = databaseMetaData.getDatabaseProductName().toLowerCase();
                if (lowerCase.contains("mysql")) {
                    a = "MYSQL";
                } else if (lowerCase.contains("oracle")) {
                    a = "ORACLE";
                } else if (!lowerCase.contains("sqlserver") && !lowerCase.contains("sql server")) {
                    if (!lowerCase.contains("postgresql")) {
                        throw new DBException("数据库类型:[" + lowerCase + "]不识别!");
                    }

                    a = "POSTGRESQL";
                } else {
                    a = "SQLSERVER";
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                connection.close();
            }
        }

        return a;
    }

    public static String transferDatabaseFormat(String s, String s1) {
        byte bt = -1;
        switch(s1.hashCode()) {
            case -1955532418:
                if ("ORACLE".equals(s1)) {
                    bt = 0;
                }
                break;
            case -1620389036:
                if ("POSTGRESQL".equals(s1)) {
                    bt = 1;
                }
            default:
        }

        switch(bt) {
            case 0:
                return s.toUpperCase();
            case 1:
                return s.toLowerCase();
            default:
                return s;
        }
    }


    public static Boolean isTableExist(String tableName) {
        Connection connection = null;
        ResultSet resultSet = null;

        Boolean flag;
        try {
            String[] strings = new String[]{"TABLE"};
            connection = getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            String upperCase = databaseMetaData.getDatabaseProductName().toUpperCase();
            String newTableName = transferDatabaseFormat(tableName, upperCase);
            resultSet = databaseMetaData.getTables((String)null, (String)null, newTableName, strings);
            if (resultSet.next()) {
                log.info("数据库表：【" + tableName + "】已存在");
                flag = true;
                return flag;
            }

            flag = false;
        } catch (SQLException e) {
            throw new RuntimeException();
        } finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }

                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }

        }

        return flag;
    }


    public static String getDialect(String s) throws SQLException, DBException {
        String s1 = "org.hibernate.dialect.MySQL5InnoDBDialect";
        byte bt = -1;
        switch(s.hashCode()) {
            case -1955532418:
                if ("ORACLE".equals(s)) {
                    bt = 2;
                }
                break;
            case -1620389036:
                if ("POSTGRESQL".equals(s)) {
                    bt = 1;
                }
                break;
            case 912124529:
                if ("SQLSERVER".equals(s)) {
                    bt = 0;
                }
            default:
        }

        switch(bt) {
            case 0:
                s1 = "org.hibernate.dialect.SQLServerDialect";
                break;
            case 1:
                s1 = "org.hibernate.dialect.PostgreSQLDialect";
                break;
            case 2:
                s1 = "org.hibernate.dialect.OracleDialect";
            default:
        }

        return s1;
    }

}
